﻿using UnityEngine;
using System.Collections.Generic;

namespace Inlycat
{
    /// <summary>
    /// 消息发送器
    /// </summary>
    public class MessageDispatcher
    {
        /// <summary>
        /// 无额外信息
        /// </summary>
        private const int NO_EXTRA_INFO = 0;

        /// <summary>
        /// 消息列表
        /// </summary>
        private List<Telegram> telegramList;

        /// <summary>
        /// 接收者收到消息
        /// </summary>
        /// <param name="receiver">接收者</param>
        /// <param name="telegram">消息数据</param>
        private void Discharge(BaseGameEntity receiver, Telegram telegram)
        {
            receiver.HandleMessage(telegram);
        }

        /// <summary>
        /// 发送者发送消息（无额外信息）
        /// </summary>
        /// <param name="delay">延时</param>
        /// <param name="sender">发送者实体ID</param>
        /// <param name="receiver">接收者实体ID</param>
        /// <param name="msg">消息值</param>
        public void DispatchMessage(double delay, int sender, int receiver, int msg)
        {
            DispatchMessage(delay, sender, receiver, msg, NO_EXTRA_INFO);
        }
        
        /// <summary>
        /// 发送者发送消息
        /// </summary>
        /// <param name="delay">延时</param>
        /// <param name="sender">发送者实体</param>
        /// <param name="receiver">接收者实体</param>
        /// <param name="msg">消息值</param>
        /// <param name="extraInfo">额外信息</param>
        public void DispatchMessage(double delay, int sender, int receiver, int msg, object extraInfo)
        {
            Telegram telegram = new Telegram(sender, receiver, msg, 0, extraInfo);

            /* 如果无延迟，立即发送 */
            if (delay <= 0)
            {
                BaseGameEntity receiverEntity = EntityManager.Instance.GetEntityFromID(receiver);

                if (receiverEntity == null)
                {
                    Debug.LogWarning(string.Format("MessageDispatcher.DispatchMessage({0}, {1}, {2}, {3}, {4}) ERROR: Unknow Receiver[{5}]!", delay, sender, receiver, msg, extraInfo, receiver));
                    return;
                }

                Discharge(receiverEntity, telegram);

                /* 否则加入队列，等待时间到了再发送 */
            }
            else
            {

                double currentTime = (double)Time.time;
                telegram.dispatchTime = currentTime + delay;

                telegramList.Add(telegram);
                telegramList.Sort(TelegramCompare);
            }
        }

        /// <summary>
        /// 检测并发送延迟消息,该方法被主游戏循环调用
        /// </summary>
        public void DispatchDelayedMessages()
        {
            double currentTime = (double)Time.time;

            while (telegramList.Count > 0 && telegramList[0].dispatchTime < currentTime)
            {
                Telegram telegram = telegramList[0];
                BaseGameEntity receiverEntity = EntityManager.Instance.GetEntityFromID(telegram.receiver);
                Discharge(receiverEntity, telegram);
                telegramList.RemoveAt(0);
            }
        }

        /// <summary>
        /// 清除所有消息
        /// </summary>
        public void Clear()
        {
            telegramList.Clear();
        }

        /// <summary>
        /// 消息排序
        /// </summary>
        /// <param name="tA"></param>
        /// <param name="tb"></param>
        /// <returns></returns>
        private int TelegramCompare(Telegram tA, Telegram tb)
        {
            if (tA.dispatchTime > tb.dispatchTime)
            {
                return 1;
            }
            if (tA.dispatchTime < tb.dispatchTime)
            {
                return -1;
            }
            if (tA.ID > tb.ID)
            {
                return 1;
            }
            if (tA.ID < tb.ID)
            {
                return -1;
            }

            return 0;
        }

        /// <summary>
        /// 单例
        /// </summary>
        private static MessageDispatcher _instance;

        /// <summary>
        /// 单例
        /// </summary>
        public static MessageDispatcher Instance
        {
            get { return _instance = _instance ?? new MessageDispatcher(); }
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        private MessageDispatcher()
        {
            telegramList = new List<Telegram>();
        }
    }
}